﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Fixx.Connector;
using System.Text.RegularExpressions;

namespace FixxVS
{
	public partial class ColumnSettings : UserControl
	{
		class ColumnListItem
		{
			public FixxVSSettings.IssueListviewColumn Col { get; set; }
			public FixxVSSettings.IssueListviewColumnSize Size { get; set; }
			public bool Visible { get; set; }
		}
		public delegate void ColumnChangedHandler(object sender, ColumnSettingsChangeArgs ca);
		public event ColumnChangedHandler Change = delegate { };

		private List<ColumnListItem> _Items { get; set; }
		private FixxVSSettings.IssueListviewColumn? _Selected { get; set; }
		
		public ColumnSettings()
		{
			InitializeComponent();
		}

		private void ColumnSettings_Load(object sender, EventArgs e)
		{
			this._Items = new List<ColumnListItem>();
			var store = new FixxPersistantStorage();
			var fs = (FixxVSSettings)store.Repository.FixxSettings;
			var config = fs.IssueListviewColumnConfig;

			if (store != null && store.Repository != null && store.Repository.FixxSettings != null)
			{
				foreach (var ci in config)
				{
					this._Items.Add(new ColumnListItem()
					{
						Col = ci.Key,
						Size = ci.Value,
						Visible = true
					});

				}
				foreach (FixxVSSettings.IssueListviewColumn enumVal in Enum.GetValues(typeof(FixxVSSettings.IssueListviewColumn)))
				{
					if (config.ContainsKey(enumVal))
						continue;

					this._Items.Add(new ColumnListItem()
					{
						Col = enumVal,
						Size = FixxVSSettings.IssueListviewColumnSize.SizeToCaption,
						Visible = false
					});
				}
				this.RedrawListView();
			}
		}

		private void ThrowChangedEvent()
		{
			var x = from i in this._Items
					where i.Visible == true
					select i;
			var e = new ColumnSettingsChangeArgs()
			{
				IssueListviewColumnConfig = new Dictionary
				<
					FixxVSSettings.IssueListviewColumn,
					FixxVSSettings.IssueListviewColumnSize
				>()
			};
			x.ToList().ForEach(i => e.IssueListviewColumnConfig.Add(i.Col, i.Size));
			
			this.Change(this, e);
		}

		private void lvColumns_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (this.lvColumns.SelectedItems.Count <= 0)
				return; 

			this.tbColumnActions.Enabled = true;
			this.btnVisible.Checked = false;
			this.btnDown.Enabled = false;
			this.btnUp.Enabled = false;
			this.btnSizeMode.Enabled = false;

			if (this.lvColumns.SelectedItems[0].Group == this.lvColumns.Groups[0])
			{
				var i = ((ColumnListItem)this.lvColumns.SelectedItems[0].Tag);
				int index = this._Items.IndexOf(i);
				bool downEnabled = (index != (this._Items.Count() - 1) && this._Items[index + 1].Visible);
				this.btnDown.Enabled = downEnabled;
				this.btnUp.Enabled = (index != 0);
				this.btnSizeMode.Enabled = true;
				this.btnVisible.Checked = true;
			}

			this._Selected = ((ColumnListItem)this.lvColumns.SelectedItems[0].Tag).Col;
		}

		private void btnUp_Click(object sender, EventArgs e)
		{
			var i = ((ColumnListItem)this.lvColumns.SelectedItems[0].Tag);
			int index = this._Items.IndexOf(i);
			if (index != 0)
			{
				this._Items.RemoveAt(index);
				this._Items.Insert(index - 1, i);
				this.RedrawListView();
				this.ThrowChangedEvent();
			}
			
		}

		private void btnVisible_Click(object sender, EventArgs e)
		{
			bool visible = this.btnVisible.Checked;
			var itemIndex = this.lvColumns.SelectedIndices[0];
			if (itemIndex < 0)
				return;

			((ColumnListItem)this.lvColumns.SelectedItems[0].Tag).Visible = visible;
			this.RedrawListView();
			this.ThrowChangedEvent();
		}
	
		private void RedrawListView()
		{
			this.lvColumns.BeginUpdate();
			this.lvColumns.Items.Clear();
			foreach (var c in this._Items)
			{
				string text = Regex.Replace(c.Col.ToString(), "(?!^)([A-Z])", " $1");
				string sizeText = Regex.Replace(c.Size.ToString(), "(?!^)([A-Z])", " $1");
				int index = (c.Visible) ? 0 : 1;
				var item = new ListViewItem(text);
				item.SubItems.Add(sizeText);
				item.Group = this.lvColumns.Groups[index];
				item.Tag = c;
				if (this._Selected != null && this._Selected == c.Col)
				{
					item.Selected = true;
					item.EnsureVisible();
				}
				this.lvColumns.Items.Add(item);

			}
			this.lvColumns.EndUpdate();
		}

		private void btnDown_Click(object sender, EventArgs e)
		{
			var i = ((ColumnListItem)this.lvColumns.SelectedItems[0].Tag);
			int index = this._Items.IndexOf(i);
			if (index != (this._Items.Count() - 1) && this._Items[index + 1].Visible)
			{
				this._Items.RemoveAt(index);
				this._Items.Insert(index + 1, i);
				this.RedrawListView();
				this.ThrowChangedEvent();
			}
		}

		private void btnSizeMode_Click(object sender, EventArgs e)
		{
			bool visible = this.btnVisible.Checked;
			var itemIndex = this.lvColumns.SelectedIndices[0];
			if (itemIndex < 0)
				return;
			
			var item = ((ColumnListItem)this.lvColumns.SelectedItems[0].Tag);
			item.Size = (item.Size == FixxVSSettings.IssueListviewColumnSize.SizeToContent)
				? FixxVSSettings.IssueListviewColumnSize.SizeToCaption
				: FixxVSSettings.IssueListviewColumnSize.SizeToContent ;
			this.RedrawListView();
			this.ThrowChangedEvent();
		}
	}
}
